package com.yxx.sys.common;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.core.util.ZipUtil;
import cn.hutool.poi.excel.ExcelReader;
import cn.hutool.poi.excel.ExcelUtil;
import cn.hutool.poi.excel.ExcelWriter;
import com.yxx.data.common.ConstastMapInt2Word;
import com.yxx.data.common.DataConstast;
import com.yxx.data.excelDomain.ExcelWound;
import com.yxx.data.domain.Wound;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.*;

/**
 * 文件工具类
 */
public class AppFileUtils {
    //文件上传的默认保存路径
    public static String UPLOAD_PATH = "c:/upload/";
    //创面图片上传的默认保存地址
    public static String UPLOAD_CM_PATH = "c:/upload/CM/";
    //创面标注图片上传的默认保存地址
    public static String UPLOAD_CM_LABEL_PATH = "c:/upload/CM_LABEL/";
    //文件下载的临时地址
    public static String DOWNLOAD_PATH = "c:/upload/";


    //默认图片相对地址
    public static String DEFAULT_IMG_RELA_PATH= "defaultImage.png";


    static {
        //读取配置文件的存储地址
        InputStream stream = AppFileUtils.class.getClassLoader().getResourceAsStream("file.properties");
        Properties properties=new Properties();
        try {
            properties.load(stream);
        } catch (IOException e) {
            e.printStackTrace();
        }
        String upload_path = properties.getProperty("upload_path");
        String download_path = properties.getProperty("download_path");
        if(null!=upload_path) {
          UPLOAD_PATH=upload_path;
          UPLOAD_CM_PATH=UPLOAD_PATH+"CM/";
          UPLOAD_CM_LABEL_PATH=UPLOAD_PATH+"CM_LABEL/";
        }
        if(null!=download_path) {
          DOWNLOAD_PATH=download_path;
        }
    }





    /**
     * 文件上传 返回相对路劲
     */
    public static String uploadFile(MultipartFile mf,String basePath){
      //1.得到文件名
      String oldFileName = mf.getOriginalFilename();
      //2.根据旧的文件名生成新的文件名
      String newFileName=AppFileUtils.createNewFileName(oldFileName).replaceAll("\\.", "_tmp.");
      //3.得到当前日期的字符串
      String dirName= DateUtil.format(new Date(), "MM-dd");
      String year= DateUtil.format(new Date(), "yyyy");
      //4.构造文件夹
      String absoluteDirName=basePath+"/"+year+"/"+dirName;
      String relativeDirName="/"+year+"/"+dirName;
      File absoluteDir=new File(absoluteDirName);
      //5.判断当前文件夹是否存在
      if(!absoluteDir.exists()) {
        //如果不存在则创建新文件夹
        absoluteDir.mkdirs();
      }
      //6.构造文件对象
      File file=new File(absoluteDir+"/"+newFileName);
      //7.把mf里面的图片信息写入file
      try {
        mf.transferTo(file);
      } catch (Exception e) {
        e.printStackTrace();
        return "";
      }
      return relativeDirName+"/"+newFileName;
    }



    /**
     * 文件下载
     */
    public static ResponseEntity<Object> createResponseEntity(String path,String type){
        //1,构造文件对象
        File file=new File(AppFileUtils.UPLOAD_CM_PATH+path);
        if(StrUtil.isNotBlank(type) && type.equals(DataConstast.CMZip))
            file=new File(AppFileUtils.DOWNLOAD_PATH,path);
        else if(StrUtil.isNotBlank(type) && type.equals(DataConstast.CMImg)){
            file=new File(AppFileUtils.UPLOAD_CM_PATH+path);
        }
        else if(StrUtil.isNotBlank(type) && type.equals(DataConstast.CMLabel)){
          file=new File(AppFileUtils.UPLOAD_CM_LABEL_PATH+path);
        }
        if (file.exists()){
            //将下载的文件,封装byte[]
            byte[] bytes= null;
            bytes = FileUtil.readBytes(file);
            //创建封装响应头信息的对象
            HttpHeaders header=new HttpHeaders();
            //封装响应内容类型(APPLICATION_OCTET_STREAM 响应的内容不限定)
            header.setContentType(MediaType.APPLICATION_OCTET_STREAM);
            //创建ResponseEntity对象
            ResponseEntity<Object> entity=
                    new ResponseEntity<Object>(bytes, header, HttpStatus.CREATED);
            return entity;
        }
        return null;
    }
    /***
      *@Description: 解压zip文件
       * @param zipFilePath
     * @param destPath
      * @return: void
      **/
    public static void unZip(String zipFilePath,String destPath ) {
      try {
//        ZipFile zip = new ZipFile(zipFilePath);
//        /*zip4j默认用GBK编码去解压,这里设置编码为GBK的*/
//        zip.setFileNameCharset("GBK");
//        zip.extractAll(destPath);

        ZipUtil.unzip(zipFilePath,destPath);
      } catch (Exception e) {
        e.printStackTrace();
      }
    }


    /***
      *@Description: 今天的文件夹中是否包含文件名为pictureId的图片
       * @param pictureId 图片名
      * @return: String 图片存储的相对地址
      **/
    public static String existTodayFile(String pictureId) {
      String dirName= DateUtil.format(new Date(), "MM-dd");
      String year= DateUtil.format(new Date(), "yyyy");
      //4.构造文件夹
      String absoluteFilePath=AppFileUtils.UPLOAD_CM_PATH+year+"/"+dirName+"/"+pictureId+".jpg";
      String relativeFilePath="/"+year+"/"+dirName+"/"+pictureId+".jpg";
      File absoluteFile=new File(absoluteFilePath);
      if(absoluteFile.exists()) {
        //如果存在
        return relativeFilePath;
      }
      return "";
    }

    public static String createWoundZip(List<Wound> woundList){

      /*
       *   数据处理
       * */
      List<ExcelWound> partWoundList =new ArrayList();
      List<String> picturePathList = new ArrayList<>();
      for (int i = 0; i <woundList.size(); i++) {
        ExcelWound partWound = new ExcelWound();
        BeanUtil.copyProperties(woundList.get(i),partWound);
        partWoundList.add(partWound);
        picturePathList.add(woundList.get(i).getPicturePath());
      }



      /*
       *   文件夹处理
       * */

      String dirName= DateUtil.format(new Date(), "MM-dd");
      String year= DateUtil.format(new Date(), "yyyy");
      String fatherDir=AppFileUtils.DOWNLOAD_PATH+year;
      String absoluteDirName=fatherDir+"/"+dirName;
      String zipDirPath=fatherDir+"/"+"zip";
      String relativeZipDirPath="/"+year+"/zip";
      File absoluteDir=new File(absoluteDirName);
      if(!absoluteDir.exists()) {
        //如果不存在则创建新文件夹
        absoluteDir.mkdirs();
      }

      /*
       *   excel制作
       * */
      String excelPath=absoluteDirName+"/img.xlsx";
      ExcelWriter writer = ExcelUtil.getWriter(excelPath);
      //自定义标题别名
      writer.addHeaderAlias("pictureId", "照片编号（患者编号+伤后第几天）");
      writer.addHeaderAlias("patientId", "患者编号");
      writer.addHeaderAlias("name", "患者姓名");
      writer.addHeaderAlias("age", "年龄（岁，未录入请填-1）");
      writer.addHeaderAlias("sex", "性别（男/女/数据未录入）");

      writer.addHeaderAlias("height", "身高（厘米，未录入请填-1）");
      writer.addHeaderAlias("weight", "体重（千克，未录入请填-1）");
      writer.addHeaderAlias("cureDay", "治愈时间（天，未录入请填-1）");
      writer.addHeaderAlias("reason", "致伤原因");
      writer.addHeaderAlias("area", "烧伤总面积（平方厘米，未录入请填-1）");

      writer.addHeaderAlias("depth", "烧伤深度（一度/浅二度/深二度/三度/数据未录入）");
      writer.addHeaderAlias("position", "烧伤部位");
      writer.addHeaderAlias("hasInfected", "创面感染（是/否/数据未录入）");
      writer.addHeaderAlias("complications", "合并并发症");
      writer.addHeaderAlias("healing", "愈合情况");

      writer.addHeaderAlias("hasLenLiao", "冷疗（是/否/数据未录入）");
      writer.addHeaderAlias("hasJiaoYuanMei", "胶原酶使用（是/否/数据未录入）");
      writer.addHeaderAlias("fuLiaoType", "敷料类型（生物敷料/合成敷料/传统纱布/数据未录入）");
      writer.addHeaderAlias("fuLiaoDetail", "具体敷料明细");
      writer.addHeaderAlias("hasQingChuang", "清创（是/否/数据未录入）");

      writer.addHeaderAlias("qingChuangTime", "清创手术时间（未录入请填1900/1/1）");
      writer.addHeaderAlias("hasZhiPi", "植皮（是/否/数据未录入）");
      writer.addHeaderAlias("zhiPiTime", "植皮手术时间（未录入请填1900/1/1）");
      writer.addHeaderAlias("zhiPiDepth", "植皮厚度（未植皮/刃厚/中厚/全厚/数据未录入）");
      writer.addHeaderAlias("zhiPiType", "植皮具体类型");

      writer.addHeaderAlias("painScore", "换药疼痛评分");
      writer.addHeaderAlias("yanzhengScore", "创面炎症评分");
      writer.addHeaderAlias("afterHurtDay", "伤后第几天（天，未录入请填-1）");

      writer.write(partWoundList);
      writer.close();


      //读入数据 修改数据
      ExcelReader reader = ExcelUtil.getReader(FileUtil.file(excelPath));
      List<List<Object>> excelContent = reader.read();
      for (int i = 1; i <excelContent.size(); i++) {
        List<Object> objects = excelContent.get(i);
        //性别转换
        objects.set(4, ConstastMapInt2Word.sexMap.get(Integer.parseInt(objects.get(4).toString())));
        //烧伤深度转化
        objects.set(10, ConstastMapInt2Word.depthMap.get(Integer.parseInt(objects.get(10).toString())));
        //创面感染
        objects.set(12, ConstastMapInt2Word.trueFalseMap.get(Integer.parseInt(objects.get(12).toString())));
        //冷疗
        objects.set(15, ConstastMapInt2Word.trueFalseMap.get(Integer.parseInt(objects.get(15).toString())));
        //胶原酶使用
        objects.set(16, ConstastMapInt2Word.trueFalseMap.get(Integer.parseInt(objects.get(16).toString())));
        //敷料类型
        objects.set(17, ConstastMapInt2Word.fuLiaoTypeMap.get(Integer.parseInt(objects.get(17).toString())));
        //清创
        objects.set(19, ConstastMapInt2Word.trueFalseMap.get(Integer.parseInt(objects.get(19).toString())));
        //清创时间
        Date qingChuangTime = DateUtil.parse(objects.get(20).toString());
        String qingChuangTimeStr = DateUtil.formatDate(qingChuangTime);
        objects.set(20, qingChuangTimeStr);
        //植皮
        objects.set(21, ConstastMapInt2Word.trueFalseMap.get(Integer.parseInt(objects.get(21).toString())));
        //植皮时间
        Date zhiPiTime = DateUtil.parse(objects.get(22).toString());
        String zhiPiTimeStr = DateUtil.formatDate(zhiPiTime);
        objects.set(22, zhiPiTimeStr);
        //植皮厚度
        objects.set(23, ConstastMapInt2Word.zhiPiDepthMap.get(Integer.parseInt(objects.get(23).toString())));
      }
      reader.close();
      writer = ExcelUtil.getWriter(excelPath);
      writer.write(excelContent);
      writer.close();


      /*
       *   图片复制
       * */
      String absoluteImgDirName=absoluteDirName+"/img";
      File absoluteImgDir=new File(absoluteImgDirName);
      if(!absoluteImgDir.exists()) {
        //如果不存在则创建新文件夹
        absoluteImgDir.mkdirs();
      }

      for (String picturePath : picturePathList) {
        String sourcePath=AppFileUtils.UPLOAD_CM_PATH+picturePath;
        String[] split = picturePath.split("/");
        String destPath=absoluteImgDirName+"/"+split[split.length-1];
        FileUtil.copy(sourcePath,destPath,true);
      }

      /*
       *   压缩 并删除原文件
       * */
      String zipName=System.currentTimeMillis()+".zip";
      String zipSourcePath=fatherDir+"/"+zipName;
      String zipDestPath=zipDirPath+"/"+zipName;
      ZipUtil.zip(absoluteDirName,zipSourcePath);
      FileUtil.move(FileUtil.file(zipSourcePath),FileUtil.file(zipDestPath),true);
      AppFileUtils.removeFile(FileUtil.file(excelPath));
      AppFileUtils.removeDirectory(FileUtil.file(absoluteImgDirName));
      //返回相对地址
      return relativeZipDirPath+"/"+ zipName;
    }






    /**
     * 根据文件老名字得到新名字
     */
    public static String createNewFileName(String oldName){
      String substr = oldName.substring(oldName.lastIndexOf("."), oldName.length());
      return IdUtil.simpleUUID().toUpperCase()+substr;
    }

    /***
      *@Description:
       * @param imgPath 文件存储的相对路径
     * @param name 文件名 不需要后缀
      * @return: java.lang.String  返回改名之后的图片的相对路径
      **/
    public static String renameFile(String imgPath,String name,String basePath) {
      File file = new File(basePath,imgPath);
      String[] split = imgPath.split("/");
      String replace=imgPath.replace(split[split.length-1].split("\\.")[0],name);
      if (file.exists()){
        file.renameTo(new File(basePath,replace));
      }
      return replace;
    }
    //删除文件
    public static boolean removeFile(File file) {
        if (file.exists()){
            file.delete();
            return true;
        }
        return false;
    }
    //删除文件夹
    public static void removeDirectory(File directory) {
      File[] files=directory.listFiles();
      //循环遍历数组中的所有子文件和文件夹
      if (files!=null){
        //判断是否是文件，如果是，就删除
        for (File file1 : files) {
          if (file1.isFile()) {
            file1.delete();
          }
          //在循环中，判断遍历出的是否是文件夹
          if (file1.isDirectory()){
            // 如果是文件夹,就递归删除里面的文件
            AppFileUtils.removeDirectory(file1);
            // 删除该文件夹里所有文件后,当前文件夹就为空了,那么就可以删除该文件夹了
            file1.delete();
          }
        }
      }
      directory.delete();
    }
    /*
    *   输入绝对地址 返回相对地址
    * */
    public static String getRelativePath(String absolutePath) {
      return "/"+absolutePath.replace("\\","/").replace(AppFileUtils.UPLOAD_CM_PATH, "");
    }




}
